package com.iyoudoock.citymine;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.DrawableRes;
import android.support.annotation.LayoutRes;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.iyoudoock.citymine.bean.UserBean;
import com.iyoudoock.citymine.broadcast.NetReceiver;
import com.iyoudoock.citymine.constants.HttpUtils;
import com.iyoudoock.citymine.constants.Key;
import com.iyoudoock.citymine.constants.Value;
import com.iyoudoock.citymine.utils.SystemUtils;
import com.kvin.toolkit.activity.OnBindInit;
import com.kvin.toolkit.activity.OnHandleMessageListener;
import com.kvin.toolkit.activity.OnNavClickListener;
import com.kvin.toolkit.activity.OnNavInit;
import com.kvin.toolkit.receiver.OnReceiveListener;
import com.kvin.toolkit.utils.LogUtils;
import com.kvin.toolkit.utils.PersistentUtils;
import com.kvin.toolkit.utils.StringUtils;
import com.kvin.toolkit.utils.ThreadPoolUtils;
import com.kvin.toolkit.utils.TipsUtils;
import com.kvin.toolkit.utils.ToastUtils;
import com.kvin.toolkit.utils.http.JsonHttpResponse;
import com.kvin.toolkit.utils.http.JsonUtils;
import com.kvin.toolkit.utils.region.ProvinceBean;
import com.kvin.toolkit.utils.region.RegionUtils;
import com.kvin.toolkit.utils.system.AnimUtils;
import com.kvin.toolkit.utils.system.NetUtils;
import com.kvin.toolkit.widget.LoadingDialog;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.TimerTask;

public class BaseActivity extends AppCompatActivity implements OnHandleMessageListener, View.OnClickListener, OnNavInit, OnNavClickListener, OnBindInit, JsonHttpResponse {
    protected final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            onHandleMessage(msg);
        }
    };
    protected Message mMessage;
    protected PersistentUtils mPersistentUtils;
    private RelativeLayout mContainer;
    private android.widget.TextView titleText;
    protected Toolbar toolbar;
    private FloatingActionButton fab;
    protected Menu mMenu;

    private boolean initialized;
    private long exitTime;
    private NetReceiver mNetReceiver;
    private boolean first;


    protected JsonUtils mJsonUtils;
    protected HashMap<String, String> params;

    protected String mUid;
    protected String mMacId;
    protected String mLongitude;
    protected String mLatitude;

    protected Intent mIntent;
    protected Bundle mBundle;


    protected boolean isRunning;
    protected boolean isCARunning;//current activity
    protected LoadingDialog mLoadingDialog;
    protected String mRoleType;
    protected String phoneNo;
    protected String userName;
    protected String userPsw;
    protected int state;
    protected String msg;

    protected TipsUtils mTips;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.setContentView(R.layout.activity_base);
        this.fab = (FloatingActionButton) findViewById(R.id.fab);
        this.fab.setVisibility(View.GONE);
        this.toolbar = (Toolbar) findViewById(R.id.toolbar);
        this.toolbar.setTitle("");
        this.toolbar.setNavigationIcon(R.mipmap.nav_back);
        this.titleText = (TextView) findViewById(R.id.title_text);
        this.mContainer = (RelativeLayout) findViewById(R.id.base_container);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setHomeButtonEnabled(true);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }
        initConfig();
        initialized = false;
        mMacId = SystemUtils.getMac(this);
    }

    private void initConfig() {
        BaseApp.getInstance().addAct(getActivity());
        mPersistentUtils = PersistentUtils.getInstance(this, PersistentUtils.XmlFile.USER_INFO);
        mUid = mPersistentUtils.readString(Key.User.UID);
        mLongitude = mPersistentUtils.readString(Key.User.LONGITUDE);
        mLatitude = mPersistentUtils.readString(Key.User.LATITUDE);
        mLoadingDialog = LoadingDialog.newLoadingDialog(getActivity());

        this.fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onFabClick(v);
            }
        });

        this.toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onBackClick(view);
            }
        });
    }


    @Override
    protected void onStart() {
        super.onStart();
        if (!initialized) {
            initialized = true;
            initNav();
            init();
        }
    }


    @Override
    protected void onResume() {
        super.onResume();
        initDialog();
        isRunning = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        isRunning = false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.clear();
        onNavNextIcon(menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        onNextClick(item);
        return super.onOptionsItemSelected(item);
    }


    /**
     * add to black list
     */
    public void addToBlacklist(String targetUid) {
        mJsonUtils = JsonUtils.getInstance();
        params = HttpUtils.addToCollectOrBlackList(mUid, targetUid, Value.Type.BALCKLIST);
        mJsonUtils.post(HttpUtils.ADD_BLACKLIST_URL, params, this, Value.Flag.ADD_TO_BLACKLIST);
    }

    /**
     * remove from black list
     */
    public void removeFromBlacklist(String targetUid) {
        mJsonUtils = JsonUtils.getInstance();
        params = HttpUtils.removeFromCollectOrBlackList(mUid, targetUid, Value.Type.BALCKLIST);
        mJsonUtils.post(HttpUtils.REMOVE_BLACKLIST_URL, params, this, Value.Flag.REMOVE_FROM_BLACKLIST);
    }


    /**
     * register or unregister net receiver
     */
    public void registerNetReceiver() {
        first = true;
        mNetReceiver = new NetReceiver();
        mNetReceiver.setOnReceiveListener(mOnReceiveListener);
        IntentFilter mFilter = new IntentFilter(Value.Action.NET_STATE_CHANGE);
        registerReceiver(mNetReceiver, mFilter);
    }

    public void unregisterNetReceiver() {
        if (mNetReceiver != null)
            unregisterReceiver(mNetReceiver);
    }

    /**
     * net on receiver listener
     * auto login when net is ok
     */
    private OnReceiveListener mOnReceiveListener = new OnReceiveListener() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (NetUtils.isNetConnected(context) && first) {
                if (TextUtils.isEmpty(mUid)) {
                    phoneNo = mPersistentUtils.readString(Key.User.TELEPHONE);
                    userPsw = mPersistentUtils.readString(Key.User.PASSWORD);
                    if (TextUtils.isEmpty(phoneNo) || TextUtils.isEmpty(userPsw)) return;
                    login(phoneNo, userPsw);
                }
            }
        }
    };

    /**
     * press again  exit
     */
    public void pressAgainExit() {
        if (System.currentTimeMillis() - exitTime > 2 * 1000) {
            exitTime = System.currentTimeMillis();
            ToastUtils.simpleToast(getActivity(), "再按一次，退出程序！");
        } else {
//            getActivity().finish();
            BaseApp.getInstance().exit();
        }
    }

    /**
     * add content view
     *
     * @param res
     */
    public void setContentView(@LayoutRes int res) {
        View v = LayoutInflater.from(this).inflate(res, null);
        this.mContainer.addView(v, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    }

    public void setContentViewWithoutBar(@LayoutRes int res) {
        super.setContentView(res);
    }


    /**
     * get verify code
     *
     * @param verifyType {=0 update psw   =1 register}
     */
    public void getVerifyCode(String phoneNo, int verifyType) {
        if (TextUtils.isEmpty(phoneNo)) {
            ToastUtils.simpleToast(getActivity(), R.string.tip_phone_no_null);
            return;
        }
        params = HttpUtils.getVerifyCodeParams(phoneNo, String.valueOf(verifyType));
        mJsonUtils = JsonUtils.getInstance();
        mJsonUtils.post(HttpUtils.VERIFY_CODE_URL, params, this, Value.Flag.VERIFY_CODE);
    }

    /**
     * get verify code
     */
    public void checkVerifyCode(String phoneNo, String verifyCode) {
        params = HttpUtils.checkVerifyCode(phoneNo, verifyCode);
        mJsonUtils = JsonUtils.getInstance();
        mJsonUtils.post(HttpUtils.CHECK_VERIFYCODE_URL, params, this, Value.Flag.CHECK_VERIFY_CODE);
    }

    /**
     * check verify code response
     *
     * @param response
     */
    private void handleCheckVerifyCodeResponse(JSONObject response) {
        try {
            int state = response.getInt(Key.Tag.STATE);
            if (state == Value.Response.SUCCESS) {
                mHandler.sendEmptyMessage(Value.Message.VERIFY_SUCCESS);
            } else {
                mHandler.sendEmptyMessage(Value.Message.VERIFY_FAILURE);
                ToastUtils.simpleToast(getActivity(), R.string.tip_verify_code_error);
            }
        } catch (JSONException e) {
            e.printStackTrace();
            mHandler.sendEmptyMessage(Value.Message.VERIFY_FAILURE);
        }
    }


    /**
     * login
     */
    public void login(String userName, String psw) {
        mMacId = SystemUtils.getMac(this);
        mJsonUtils = JsonUtils.getInstance();
        HashMap<String, String> params = HttpUtils.getLoginParams(mMacId, userName, psw);
        mJsonUtils.post(HttpUtils.LOGIN_URL, params, this, Value.Flag.LOGIN);
    }

    /**
     * handle login response
     *
     * @param response
     */
    private void handleLoginResponse(JSONObject response) {
        try {
            state = response.getInt(Key.Tag.STATE);
            if (state != Value.Response.SUCCESS) {
                msg = response.getString(Key.Tag.MSG);
                ToastUtils.simpleToast(getActivity(), msg);
                return;
            }
            String s = response.getString(Key.Tag.DATA);
            if (StringUtils.isEmpty(s)) return;
            UserBean bean = JSON.parseObject(s, UserBean.class);
            //store user info
            writeUserInfo(bean);
            ToastUtils.simpleToast(getActivity(), getString(R.string.login_success));
            mHandler.sendEmptyMessage(Value.Message.LOGIN_SUCCESS);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * logout
     */
    public void logout() {
        mUid = mPersistentUtils.readString(Key.User.UID);
        if (TextUtils.isEmpty(mUid)) {
            ToastUtils.simpleToast(getActivity(), "已经退出登入了！");
            return;
        }
        mLongitude = mPersistentUtils.readString(Key.User.LONGITUDE);
        mLatitude = mPersistentUtils.readString(Key.User.LATITUDE);
//        String locationStatus = mPersistentUtils.readString(Key.User.LOCATION_STATUS);
        HashMap<String, String> params = HttpUtils.logout(mUid, mLatitude, mLongitude, mMacId);
        mJsonUtils = JsonUtils.getInstance();
        mJsonUtils.post(HttpUtils.LOGOUT_URL, params, this, Value.Flag.LOGOUT);
    }

    /**
     * is login
     */
    public void checkLoginState() {
        if (TextUtils.isEmpty(mUid)) return;
        mJsonUtils = JsonUtils.getInstance();
        mMacId = SystemUtils.getMac(this);
        params = HttpUtils.isLogin(mUid, mMacId);
        mJsonUtils.post(HttpUtils.IS_LOGIN_URL, params, this, Value.Flag.CHECK_LOGIN_STATE);
    }


    /**
     * upload latlng
     */
    public void uploadLatLng(String latitude, String longitude) {
        mMacId = SystemUtils.getMac(this);
        params = HttpUtils.uploadlatlng(mUid, latitude, longitude, mMacId);
        mJsonUtils=JsonUtils.getInstance();
        mJsonUtils.post(HttpUtils.UPLOAD_LATLNG,params,this,Value.Flag.UPLOAD_LATLNG);
    }

    /**
     * handle logout response
     *
     * @param response
     */
    private void handleLogoutResponse(JSONObject response) {
        try {
            int state = response.getInt(Key.Tag.STATE);
            if (state == 1) {
                ToastUtils.simpleToast(getActivity(), "退出成功");
                //clear stored info
                clearUserInfo();
                mHandler.sendEmptyMessage(Value.Message.LOGOUT_SUCCESS);
                //mapLeftMenu.showMenu(false);
            } else {
                ToastUtils.simpleToast(getActivity(), "退出失败");
            }
            //mLoadingDialog.dismiss();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * change identity
     */
    public void changeIdentity(String districtId, String roleType) {
        params = HttpUtils.changeIdentity(mUid, districtId, roleType);
        mJsonUtils = JsonUtils.getInstance();
        mJsonUtils.post(HttpUtils.CHANGE_IDENTITY_URL, params, this, Value.Flag.CHANGE_IDENTITY);
    }

    /**
     * handle change identify response
     *
     * @param response
     */
    private void handleChangeIdentityResponse(JSONObject response) {
        try {
            state = response.getInt(Key.Tag.STATE);
            if (state == Value.Response.SUCCESS) {
                ToastUtils.simpleToast(getActivity(), "变更成功，我们将尽快为您审核");
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * initialize region
     */
    public void initRegion() {
        ThreadPoolUtils.execute(new TimerTask() {
            @Override
            public void run() {
                ArrayList<ProvinceBean> data = RegionUtils.loadingProvince(getActivity());
                if (data == null) return;
                mMessage = Message.obtain();
                mMessage.what = Value.Message.REGION;
                mMessage.obj = data;
                mHandler.sendMessage(mMessage);
            }
        });
    }

    /**
     * get search type
     */
    public String searchType() {
        mRoleType = mPersistentUtils.readString(Key.User.ROLE_TYPE);
        if (mRoleType.equals(Value.Role.USER) || TextUtils.isEmpty(mRoleType)) {
            return Value.Role.COMMUNITY + "," + Value.Role.FLUENT;
        }
        return Value.Role.RECYCLER;
    }

    /**
     * return overlay image
     *
     * @param type
     * @return
     */
    protected BitmapDescriptor getOverlay(String type) {
        if (type.equals(Value.Role.FLUENT)) {
            return BitmapDescriptorFactory.fromResource(R.mipmap.fluent_recycler_icon);
        } else if (type.equals(Value.Role.COMMUNITY)) {
            return BitmapDescriptorFactory.fromResource(R.mipmap.conmunity_recycler_icon);
        } else if (type.equals(Value.Role.RECYCLER)) {
            return BitmapDescriptorFactory.fromResource(R.mipmap.recycler_bin_icon);
        } else
            return BitmapDescriptorFactory.fromResource(R.mipmap.user_location_icon);
    }

    /**
     * get activity
     *
     * @return
     */
    protected Activity getActivity() {
//        LogUtils.d("------this=" + this);
        return this;
    }


    /**
     * store user info
     */
    public void writeUserInfo(UserBean bean) {
        mPersistentUtils.writeString(Key.User.UID, String.valueOf(bean.getUid()));
        mPersistentUtils.writeString(Key.User.NICK_NAME, bean.getUsername());
        mPersistentUtils.writeString(Key.User.ROLE_TYPE, bean.getType());
        mPersistentUtils.writeString(Key.User.PASSWORD, TextUtils.isEmpty(userPsw) ? "" : userPsw);
        mPersistentUtils.writeString(Key.User.TELEPHONE, bean.getTelephone());
        mPersistentUtils.writeString(Key.User.SEX, bean.getSex());
        mPersistentUtils.writeString(Key.User.AGE, bean.getAge());
        mPersistentUtils.writeString(Key.User.RECYCLER_NO, TextUtils.isEmpty(bean.getNo()) ? "" : bean.getNo());
        mPersistentUtils.writeString(Key.User.ADDRESS, bean.getAddress());
        mPersistentUtils.writeString(Key.User.AVATAR, bean.getHeadImage());
        mPersistentUtils.writeString(Key.User.LOCATION_STATUS, String.valueOf(bean.getLocationStatus()));
        mPersistentUtils.writeString(Key.User.DISTRICT, bean.getVillageName());
    }

    /**
     * clear user info
     */
    public void clearUserInfo() {
        mPersistentUtils.writeString(Key.User.UID, "");
        mPersistentUtils.writeString(Key.User.NICK_NAME, "");
        mPersistentUtils.writeString(Key.User.ROLE_TYPE, "");
        mPersistentUtils.writeString(Key.User.PASSWORD, "");
//        mPersistentUtils.writeString(Key.User.TELEPHONE, "");
        mPersistentUtils.writeString(Key.User.SEX, "");
        mPersistentUtils.writeString(Key.User.AGE, "");
        mPersistentUtils.writeString(Key.User.RECYCLER_NO, "");
        mPersistentUtils.writeString(Key.User.ADDRESS, "");
        mPersistentUtils.writeString(Key.User.AVATAR, "");
        mPersistentUtils.writeString(Key.User.LOCATION_STATUS, "");
    }


    /**
     * set title
     */
    @Override
    public void setTitle(String title) {
        this.titleText.setText(title);
    }

    /**
     * set nav icon
     */
    @Override
    public void setNavBackIcon(@DrawableRes int resId) {
        if (resId == -1) {
            return;
        }
        this.toolbar.setNavigationIcon(resId);
    }

    @Override
    public void onNavNextIcon(Menu menu) {
    }


    /**
     * set fab visible
     */
    protected void setFabVisibility(int visibility) {
        this.fab.setVisibility(visibility);
    }

    protected void setNavBackVisibility(int visibility) {
        if (visibility != View.VISIBLE) {
            this.toolbar.setNavigationIcon(null);
        }
    }


    /**
     * set action bar visible
     */
    protected void hideActionbar() {
        hideActionbar(true);
    }

    protected void hideActionbar(boolean tag) {
        if (tag) {
            this.toolbar.setVisibility(View.GONE);
        } else {
            this.toolbar.setVisibility(View.VISIBLE);
        }
    }


    @Override
    public void onClick(View v) {

    }

    @Override
    public void onHandleMessage(Message msg) {
        switch (msg.what) {
            case Value.Message.LOADING_DIALOG_SHOW:
                if (isRunning)
                    mLoadingDialog.show();
                break;
            case Value.Message.LOADING_DIALOG_DISMISS:
                if (isRunning)
                    mLoadingDialog.dismiss();
                break;
        }
    }


    @Override
    public void init() {

    }

    @Override
    public void initNav() {

    }

    @Override
    public void initDialog() {

    }

    @Override
    public void loadingData() {

    }

    @Override
    public void onBackClick(View view) {
        this.finish();//default
        AnimUtils.setAnim(this, AnimUtils.AnimStyle.LEFT_IN_RIGHT_OUT);
    }

    @Override
    public void onNextClick(MenuItem menuItem) {

    }


    @Override
    public void onFabClick(View view) {

    }

    @Override
    public void onSuccess(JSONObject response, String flag) {
        mHandler.sendEmptyMessage(Value.Message.LOADING_DIALOG_DISMISS);
        if (response == null) {
            LogUtils.d("----response is null");
            return;
        }

        if (Value.Flag.LOGIN.equals(flag)) {
            //login
            handleLoginResponse(response);
        } else if (Value.Flag.LOGOUT.equals(flag)) {
            //logout
            handleLogoutResponse(response);
        } else if (Value.Flag.VERIFY_CODE.equals(flag)) {
            //get verify code
            try {
                state=response.getInt(Key.Tag.STATE);
                if (state!=Value.Response.SUCCESS){
                    msg=response.getString(Key.Tag.MSG);
                    ToastUtils.simpleToast(this,TextUtils.isEmpty(msg)?getString(R.string.tip_get_verify_fail):msg);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            LogUtils.d("---------" + response.toString());
        } else if (Value.Flag.CHECK_VERIFY_CODE.equals(flag)) {
            //check verify code
            handleCheckVerifyCodeResponse(response);
        } else if (Value.Flag.CHANGE_IDENTITY.equals(flag)) {
            //change identity
            handleChangeIdentityResponse(response);
        }else if (flag.equals(Value.Flag.UPLOAD_LATLNG)){

        }
    }

    @Override
    public void onPreExecute(String flag) {
        if (!NetUtils.isNetConnected(this)) {
            if (mJsonUtils != null) mJsonUtils.setEnabled(false);
            ToastUtils.simpleToast(getActivity(), getString(R.string.net_not_connected));
            return;
        }
        mHandler.sendEmptyMessage(Value.Message.LOADING_DIALOG_SHOW);
    }

    @Override
    public void onFailure(IOException e, String flag) {
        e.printStackTrace();
        //handle exception
        if (e instanceof SocketTimeoutException) {
            ToastUtils.simpleToast(getActivity(), R.string.exception_socket_timeout);
        } else if (e instanceof ConnectException) {
            ToastUtils.simpleToast(getActivity(), R.string.exception_connect);
        }
        mHandler.sendEmptyMessage(Value.Message.LOADING_DIALOG_DISMISS);
    }
}
